

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=&#34;light&#34;>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="https://cdn.jsdelivr.net/gh/kzwrime/kzwrime.github.io/img/favicon.png">
  <link rel="icon" type="image/png" href="https://tuchuangrrr.oss-cn-shenzhen.aliyuncs.com/img/kunnan.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="">
  <meta name="author" content="霜华">
  <meta name="keywords" content="">
  <title>Dijkstra BFS DFS 最短路径 - kunzh</title>

  <link  rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.staticfile.org/github-markdown-css/4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/lib/hint/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/10.0.0/styles/atelier-lakeside-dark.min.css" />
    
  

  


<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_pf9vaxs7x7b.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">


<link  rel="stylesheet" href="/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
</head>


<body>
  <header style="height: 60vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/">&nbsp;<strong>kunzh</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/links/">
                <i class="iconfont icon-link-fill"></i>
                友链
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/shuoshuo2/">
                <i class="iconfont icon-speakernotes"></i>
                留言板
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;</a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" href="javascript:">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner intro-2" id="background" parallax=true
         style="background: url('https://rainrime.top/img/SloveniaAlps.jpg') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="container page-header text-center fade-in-up">
            <span class="h2" id="subtitle">
              
            </span>

            
              <div class="mt-3">
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2020-07-01 16:54" pubdate>
        2020年7月1日 下午
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      2.8k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      49
       分钟
    </span>
  

  
  
    
      <!-- LeanCloud 统计文章PV -->
      <span id="leancloud-post-views-container" class="post-meta" style="display: none">
        <i class="iconfont icon-eye" aria-hidden="true"></i>
        <span id="leancloud-post-views"></span> 次
      </span>
    
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid">
  <div class="row">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-md">
      <div class="container nopadding-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto" id="post">
            <!-- SEO header -->
            <h1 style="display: none">Dijkstra BFS DFS 最短路径</h1>
            
            <div class="markdown-body" id="post-body">
              <h1 id="dijkstra-bfs-dfs-最短路径"><a class="markdownIt-Anchor" href="#dijkstra-bfs-dfs-最短路径"></a> Dijkstra BFS DFS 最短路径</h1>
<p>本文用 c 实现 <code>DFS</code>, <code>BFS</code>, <code>Dijkstra</code> 寻找最短路径的算法。伪码和图文说明可以查看本博客的 <a href="/2020/%E5%9B%BE%E8%AE%BA%E4%B8%AD%E7%9A%84%E9%87%8D%E8%A6%81%E7%AE%97%E6%B3%95/">另一篇文章</a>。</p>
<p>理论上<code>BFS</code>和<code>DFS</code>找到的只是一条路径，但加以改造(加上更新路程)也是可以找最短路径的。此外除了数据结构不同，其实我的三种实现几乎一样 。。。</p>
<p>本文的一些数据结构的函数写着写着没用到，那就放那里吧，数据结构建议不看，如有需要可以点击下面各个小三角形查看折叠的数据结构代码。</p>
<details>
<summary>链表</summary>
<pre><code class="hljs c"><span class="hljs-comment">/* 链表 */</span>
<span class="hljs-keyword">typedef</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">chainnode</span> &#123;</span>
    <span class="hljs-keyword">int</span> element;
    <span class="hljs-keyword">int</span> weight;
    <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">chainnode</span>* <span class="hljs-title">next</span>;</span>
&#125; ChainNode;

<span class="hljs-keyword">typedef</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">chain</span> &#123;</span>
    ChainNode* first;
    ChainNode* last;
&#125; chain;

<span class="hljs-function">ChainNode* <span class="hljs-title">chainBegin</span><span class="hljs-params">(chain* ch)</span></span>;
<span class="hljs-function">ChainNode* <span class="hljs-title">chainEnd</span><span class="hljs-params">(chain* ch)</span></span>;
<span class="hljs-function">chain* <span class="hljs-title">createChain</span><span class="hljs-params">()</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">emptyChain</span><span class="hljs-params">(chain* ch)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">insertChain</span><span class="hljs-params">(chain* ch, <span class="hljs-keyword">int</span> data, <span class="hljs-keyword">int</span> weight)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">chainErase</span><span class="hljs-params">(chain* ch, <span class="hljs-keyword">int</span> data)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">deleteChain</span><span class="hljs-params">(chain* ch)</span></span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">getEleChain</span><span class="hljs-params">(chain* ch, <span class="hljs-keyword">int</span> index)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">getWeight</span><span class="hljs-params">(chain* ch, <span class="hljs-keyword">int</span> data)</span></span>;
<span class="hljs-function">chain* <span class="hljs-title">read</span><span class="hljs-params">(FILE* fp, <span class="hljs-keyword">int</span> vv, <span class="hljs-keyword">int</span> ww)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">deread</span><span class="hljs-params">(chain* lnn, <span class="hljs-keyword">int</span> vv)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">popChain</span><span class="hljs-params">(chain* lnn)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">pushChain</span><span class="hljs-params">(chain* lnn, <span class="hljs-keyword">int</span> data)</span></span>;

<span class="hljs-function">ChainNode* <span class="hljs-title">chainBegin</span><span class="hljs-params">(chain* ch)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">return</span> ch-&gt;first;
&#125;

<span class="hljs-function">ChainNode* <span class="hljs-title">chainEnd</span><span class="hljs-params">(chain* ch)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">return</span> ch-&gt;last;
&#125;

<span class="hljs-function">chain* <span class="hljs-title">createChain</span><span class="hljs-params">()</span></span>
<span class="hljs-function"></span>&#123;
    chain* newChain = (chain*)<span class="hljs-built_in">malloc</span>(<span class="hljs-keyword">sizeof</span>(chain));
    newChain-&gt;first = <span class="hljs-literal">NULL</span>;
    newChain-&gt;last = <span class="hljs-literal">NULL</span>;
    <span class="hljs-keyword">return</span> newChain;
&#125;

<span class="hljs-function"><span class="hljs-keyword">inline</span> <span class="hljs-keyword">int</span> <span class="hljs-title">insertChain</span><span class="hljs-params">(chain* ch, <span class="hljs-keyword">int</span> data, <span class="hljs-keyword">int</span> weight)</span></span>
<span class="hljs-function"></span>&#123;
    ChainNode* newNode = (ChainNode*)<span class="hljs-built_in">malloc</span>(<span class="hljs-keyword">sizeof</span>(ChainNode));
    newNode-&gt;weight = weight;
    newNode-&gt;element = data;
    newNode-&gt;next = <span class="hljs-literal">NULL</span>;
    <span class="hljs-keyword">if</span> (<span class="hljs-literal">NULL</span> == ch-&gt;first) &#123;
        ch-&gt;first = newNode;
        ch-&gt;last = newNode;
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    &#125; <span class="hljs-keyword">else</span> &#123;
        ch-&gt;last-&gt;next = newNode;
        ch-&gt;last = newNode;
    &#125;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">chainErase</span><span class="hljs-params">(chain* ch, <span class="hljs-keyword">int</span> data)</span></span>
<span class="hljs-function"></span>&#123;
    ChainNode* node = ch-&gt;first;
    <span class="hljs-keyword">if</span> (node-&gt;element == data) &#123;
        ch-&gt;first = node-&gt;next;
        <span class="hljs-built_in">free</span>(node);
        node == <span class="hljs-literal">NULL</span>;
        <span class="hljs-keyword">return</span> data;
    &#125;
    ChainNode* prenode = node;
    node = node-&gt;next;
    <span class="hljs-keyword">while</span> (node != <span class="hljs-literal">NULL</span>) &#123;
        <span class="hljs-keyword">if</span> (node-&gt;element == data) &#123;
            <span class="hljs-keyword">if</span> (ch-&gt;last == node) &#123;
                ch-&gt;last = prenode;
            &#125;
            prenode-&gt;next = node-&gt;next;
            <span class="hljs-built_in">free</span>(node);
            node == <span class="hljs-literal">NULL</span>;
            <span class="hljs-keyword">return</span> data;
        &#125;
        prenode = node;
        node = node-&gt;next;
    &#125;
    <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">deleteChain</span><span class="hljs-params">(chain* ch)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">if</span> (<span class="hljs-literal">NULL</span> == ch-&gt;first) &#123;
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    &#125;
    ChainNode* node = ch-&gt;first;
    ChainNode* nextNode = node-&gt;next;
    <span class="hljs-keyword">while</span> (nextNode != <span class="hljs-literal">NULL</span>) &#123;
        <span class="hljs-built_in">free</span>(node);
        node = nextNode;
        nextNode = node-&gt;next;
    &#125;
    <span class="hljs-built_in">free</span>(node);
    <span class="hljs-built_in">free</span>(ch);
    ch = <span class="hljs-literal">NULL</span>;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">getEleChain</span><span class="hljs-params">(chain* ch, <span class="hljs-keyword">int</span> index)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">if</span> (<span class="hljs-literal">NULL</span> == ch-&gt;first) &#123;
        <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
    &#125;

    <span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>;
    ChainNode* node = ch-&gt;first;
    <span class="hljs-keyword">while</span> (node != <span class="hljs-literal">NULL</span>) &#123;
        <span class="hljs-keyword">if</span> (i == index) &#123;
            <span class="hljs-keyword">return</span> node-&gt;element;
        &#125;
        i++;
        node = node-&gt;next;
    &#125;
    <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">inline</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getWeight</span><span class="hljs-params">(chain* ch, <span class="hljs-keyword">int</span> data)</span></span>
<span class="hljs-function"></span>&#123;
    ChainNode* node = ch-&gt;first;
    <span class="hljs-keyword">while</span> (node != <span class="hljs-literal">NULL</span>) &#123;
        <span class="hljs-keyword">if</span> (node-&gt;element == data) &#123;
            <span class="hljs-keyword">return</span> node-&gt;weight;
        &#125;
        node = node-&gt;next;
    &#125;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;

<span class="hljs-function">chain* <span class="hljs-title">read</span><span class="hljs-params">(FILE* fp, <span class="hljs-keyword">int</span> vv, <span class="hljs-keyword">int</span> ww)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">int</span> a[<span class="hljs-number">3</span>];
    chain* ln = (chain*)<span class="hljs-built_in">malloc</span>(vv * <span class="hljs-keyword">sizeof</span>(chain));
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; vv; i++) &#123;
        ln[i].first = <span class="hljs-literal">NULL</span>;
        ln[i].last = <span class="hljs-literal">NULL</span>;
    &#125;
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;begin scaning....\n&quot;</span>);
    <span class="hljs-keyword">while</span> (<span class="hljs-built_in">fscanf</span>(fp, <span class="hljs-string">&quot;%d %d %d&quot;</span>, &amp;a[<span class="hljs-number">0</span>], &amp;a[<span class="hljs-number">1</span>], &amp;a[<span class="hljs-number">2</span>]) != EOF) &#123;
        insertChain(&amp;(ln[a[<span class="hljs-number">0</span>]]), a[<span class="hljs-number">1</span>], a[<span class="hljs-number">2</span>]);
        <span class="hljs-comment">// insertChain(&amp;(ln[a[1]]), a[0], a[2]); // 变为无向图，做弱连通测试</span>
    &#125;
    <span class="hljs-comment">// *lnn = ln;</span>
    <span class="hljs-comment">// printf(&quot;ln=%d\n&quot;,ln);</span>
    <span class="hljs-keyword">return</span> ln;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">deread</span><span class="hljs-params">(chain* lnn, <span class="hljs-keyword">int</span> vv)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; vv; i++) &#123;
        deleteChain(&amp;(lnn[i]));
    &#125;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">popChain</span><span class="hljs-params">(chain* lnn)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">if</span> (<span class="hljs-literal">NULL</span> == lnn-&gt;first) &#123;
        <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
    &#125;
    <span class="hljs-keyword">int</span> data = lnn-&gt;first-&gt;element;
    ChainNode* old = lnn-&gt;first;
    lnn-&gt;first = lnn-&gt;first-&gt;next;
    <span class="hljs-built_in">free</span>(old);
    <span class="hljs-keyword">return</span> data;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">pushChain</span><span class="hljs-params">(chain* lnn, <span class="hljs-keyword">int</span> data)</span></span>
<span class="hljs-function"></span>&#123;
    ChainNode* newNode;
    newNode = (ChainNode*)<span class="hljs-built_in">malloc</span>(<span class="hljs-keyword">sizeof</span>(ChainNode));
    newNode-&gt;element = data;
    newNode-&gt;next = lnn-&gt;first;
    <span class="hljs-keyword">if</span> (<span class="hljs-literal">NULL</span> == lnn-&gt;first) &#123;
        lnn-&gt;last = newNode;
    &#125;
    lnn-&gt;first = newNode;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;</code></pre>
</details>
<h2 id="dijkstra"><a class="markdownIt-Anchor" href="#dijkstra"></a> Dijkstra</h2>
<details>
<summary>优先队列（小根堆）</summary>
<pre><code class="hljs c"><span class="hljs-comment">/* 优先队列（小根堆） */</span>
<span class="hljs-keyword">typedef</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> &#123;</span>
    <span class="hljs-keyword">int</span>* heap;
    <span class="hljs-keyword">int</span> arrayLength;
    <span class="hljs-keyword">int</span> heapSize;
&#125; minHeap;
<span class="hljs-function">minHeap* <span class="hljs-title">minHeapCreate</span><span class="hljs-params">(<span class="hljs-keyword">int</span> theSize)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">popMinHeap</span><span class="hljs-params">(minHeap* mhp, <span class="hljs-keyword">int</span>* disFromSource)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">pushMinHeap</span><span class="hljs-params">(minHeap* mhp, <span class="hljs-keyword">int</span> data, <span class="hljs-keyword">int</span>* disFromSource)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">minHeapDestory</span><span class="hljs-params">(minHeap* mhp)</span></span>;

<span class="hljs-comment">// 注意堆的序号，从1开始！！！</span>

<span class="hljs-function">minHeap* <span class="hljs-title">minHeapCreate</span><span class="hljs-params">(<span class="hljs-keyword">int</span> theSize)</span></span>
<span class="hljs-function"></span>&#123;
    minHeap* mhp;
    mhp = (minHeap*)<span class="hljs-built_in">malloc</span>(<span class="hljs-keyword">sizeof</span>(minHeap));
    mhp-&gt;heapSize = <span class="hljs-number">0</span>;
    mhp-&gt;arrayLength = theSize;
    mhp-&gt;heap = (<span class="hljs-keyword">int</span>*)<span class="hljs-built_in">malloc</span>(theSize * <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">int</span>));
    <span class="hljs-keyword">return</span> mhp;
&#125;
<span class="hljs-function"><span class="hljs-keyword">inline</span> <span class="hljs-keyword">int</span> <span class="hljs-title">popMinHeap</span><span class="hljs-params">(minHeap* mhp, <span class="hljs-keyword">int</span>* disFromSource)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> == mhp-&gt;heapSize) &#123;
        <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
    &#125;

    <span class="hljs-keyword">int</span> re = mhp-&gt;heap[<span class="hljs-number">1</span>];

    <span class="hljs-keyword">int</span> lastElement = mhp-&gt;heap[mhp-&gt;heapSize--]; <span class="hljs-comment">// 先运算后自减</span>

    <span class="hljs-comment">// 为 lastElement 寻找位置</span>
    <span class="hljs-keyword">int</span> currentNode = <span class="hljs-number">1</span>;
    <span class="hljs-keyword">int</span> child = <span class="hljs-number">2</span>;
    <span class="hljs-keyword">while</span> (child &lt;= mhp-&gt;heapSize) &#123;
        <span class="hljs-comment">//  mhp-&gt;heap[child] 应该是 currentNode 更小的孩子</span>
        <span class="hljs-keyword">if</span> (child &lt; mhp-&gt;heapSize &amp;&amp; disFromSource[mhp-&gt;heap[child]] &gt; disFromSource[mhp-&gt;heap[child + <span class="hljs-number">1</span>]]) &#123;
            child++;
        &#125;

        <span class="hljs-keyword">if</span> (disFromSource[lastElement] &lt;= disFromSource[mhp-&gt;heap[currentNode]]) &#123;
            <span class="hljs-keyword">break</span>;
        &#125;

        mhp-&gt;heap[currentNode] = mhp-&gt;heap[child];
        currentNode = child;
        child *= <span class="hljs-number">2</span>;
    &#125;
    mhp-&gt;heap[currentNode] = lastElement;
    <span class="hljs-keyword">return</span> re;
&#125;
<span class="hljs-function"><span class="hljs-keyword">inline</span> <span class="hljs-keyword">void</span> <span class="hljs-title">pushMinHeap</span><span class="hljs-params">(minHeap* mhp, <span class="hljs-keyword">int</span> data, <span class="hljs-keyword">int</span>* disFromSource)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-comment">// 适当时增加堆的数组长度</span>
    <span class="hljs-keyword">if</span> (mhp-&gt;heapSize == mhp-&gt;arrayLength - <span class="hljs-number">1</span>) &#123;
        <span class="hljs-keyword">int</span>* newHeap;
        newHeap = (<span class="hljs-keyword">int</span>*)<span class="hljs-built_in">malloc</span>(mhp-&gt;arrayLength * <span class="hljs-number">2</span> * <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">int</span>));
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; mhp-&gt;arrayLength; i++) &#123;
            newHeap[i] = mhp-&gt;heap[i];
        &#125;
        <span class="hljs-built_in">free</span>(mhp-&gt;heap);
        mhp-&gt;heap = newHeap;
        mhp-&gt;arrayLength *= <span class="hljs-number">2</span>;
        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d\n&quot;</span>, mhp-&gt;arrayLength);
    &#125;

    <span class="hljs-comment">// 为 data 寻找位置</span>
    mhp-&gt;heapSize++;
    <span class="hljs-keyword">int</span> currentNode = mhp-&gt;heapSize;
    <span class="hljs-keyword">while</span> (currentNode != <span class="hljs-number">1</span> &amp;&amp; disFromSource[mhp-&gt;heap[currentNode / <span class="hljs-number">2</span>]] &gt; disFromSource[data]) &#123;
        <span class="hljs-comment">// 和父节点互换</span>
        mhp-&gt;heap[currentNode] = mhp-&gt;heap[currentNode / <span class="hljs-number">2</span>];
        currentNode /= <span class="hljs-number">2</span>;
    &#125;
    mhp-&gt;heap[currentNode] = data;
&#125;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">minHeapDestory</span><span class="hljs-params">(minHeap* mhp)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-built_in">free</span>(mhp-&gt;heap);
    mhp-&gt;heap = <span class="hljs-literal">NULL</span>;
    <span class="hljs-built_in">free</span>(mhp);
    mhp = <span class="hljs-literal">NULL</span>;
&#125;</code></pre>
</details>
<pre><code class="hljs c"><span class="hljs-comment">/* array2d 是链表数组，vv 是点的总数，source为起点, preNode和disFromSource为输出 */</span>
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">dijkstra</span><span class="hljs-params">(chain* array2d, <span class="hljs-keyword">int</span> vv, <span class="hljs-keyword">int</span> source, <span class="hljs-keyword">int</span>* preNode, <span class="hljs-keyword">int</span>* disFromSource)</span></span>
<span class="hljs-function"></span>&#123;
    chain* ln = array2d;
    minHeap* newReachableNode;  <span class="hljs-comment">// 小根堆实现的优先队列</span>
    newReachableNode = minHeapCreate((vv / <span class="hljs-number">100</span> &gt; <span class="hljs-number">20</span>) ? vv / <span class="hljs-number">100</span> : <span class="hljs-number">20</span>);

    <span class="hljs-comment">/* 所有和起点相邻的点的距离，设置他们的前一个点为起点，并全部压入优先队列 */</span>
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; vv; i++) &#123;
        disFromSource[i] = <span class="hljs-number">0</span>;
        preNode[i] = <span class="hljs-number">-1</span>;
    &#125;
    ChainNode* it = array2d[source].first;
    <span class="hljs-keyword">while</span> (it != <span class="hljs-literal">NULL</span>) &#123;
        disFromSource[it-&gt;element] = it-&gt;weight;
        preNode[it-&gt;element] = source;
        pushMinHeap(newReachableNode, it-&gt;element, disFromSource);
        it = it-&gt;next;
    &#125;
    disFromSource[source] = <span class="hljs-number">0</span>;
    preNode[source] = <span class="hljs-number">-2</span>;

    <span class="hljs-keyword">int</span> v;
    <span class="hljs-keyword">while</span> (<span class="hljs-number">0</span> != newReachableNode-&gt;heapSize) &#123;
        v = popMinHeap(newReachableNode, disFromSource);    <span class="hljs-comment">// 弹出目前距离最小的</span>

        <span class="hljs-comment">/* 更新所有和 v 相邻， 没到过或者距离可以更小的点，且没到过则入优先队列 */</span>
        ChainNode* iterator = array2d[v].first;
        <span class="hljs-keyword">while</span> (iterator != <span class="hljs-literal">NULL</span>) &#123;
            <span class="hljs-keyword">if</span> ((preNode[iterator-&gt;element] == <span class="hljs-number">-1</span> || 
                disFromSource[iterator-&gt;element] &gt; disFromSource[v] + iterator-&gt;weight)) &#123;
                disFromSource[iterator-&gt;element] = disFromSource[v] + iterator-&gt;weight;
                <span class="hljs-keyword">if</span> (<span class="hljs-number">-1</span> == preNode[iterator-&gt;element]) &#123;
                    pushMinHeap(newReachableNode, iterator-&gt;element, disFromSource);
                &#125;
                preNode[iterator-&gt;element] = v;
            &#125;
            iterator = iterator-&gt;next;
        &#125;
    &#125;
    minHeapDestory(newReachableNode);
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;</code></pre>
<h2 id="bfs"><a class="markdownIt-Anchor" href="#bfs"></a> BFS</h2>
<details>
<summary>队列</summary>
<pre><code class="hljs c"><span class="hljs-comment">/* 队列 */</span>
<span class="hljs-keyword">typedef</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">arrayQueue</span> &#123;</span>
    <span class="hljs-keyword">int</span> nOfQueue;
    <span class="hljs-keyword">int</span>* <span class="hljs-built_in">array</span>;
    <span class="hljs-keyword">int</span> writePointer, readPointer;
    <span class="hljs-keyword">int</span> <span class="hljs-built_in">free</span>;
&#125; ArrayQueue;

<span class="hljs-function">ArrayQueue* <span class="hljs-title">aCQ_create</span><span class="hljs-params">(<span class="hljs-keyword">int</span> nOfQueue)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">aCQ_delete</span><span class="hljs-params">(ArrayQueue* aCQ)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">aCQ_empty</span><span class="hljs-params">(ArrayQueue* aCQ)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">enQueue</span><span class="hljs-params">(ArrayQueue* aCQ, <span class="hljs-keyword">int</span> var)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">deQueue</span><span class="hljs-params">(ArrayQueue* aCQ)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">headOfQueue</span><span class="hljs-params">(ArrayQueue* aCQ)</span></span>;

<span class="hljs-function">ArrayQueue* <span class="hljs-title">aCQ_create</span><span class="hljs-params">(<span class="hljs-keyword">int</span> nOfQueue)</span></span>
<span class="hljs-function"></span>&#123;
    ArrayQueue* aCQ = (ArrayQueue*)<span class="hljs-built_in">malloc</span>(<span class="hljs-keyword">sizeof</span>(ArrayQueue));
    aCQ-&gt;nOfQueue = nOfQueue;
    aCQ-&gt;<span class="hljs-built_in">free</span> = nOfQueue;
    aCQ-&gt;writePointer = <span class="hljs-number">0</span>;
    aCQ-&gt;readPointer = <span class="hljs-number">0</span>;
    aCQ-&gt;<span class="hljs-built_in">array</span> = (<span class="hljs-keyword">int</span>*)<span class="hljs-built_in">malloc</span>(nOfQueue * <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">int</span>));
    <span class="hljs-keyword">return</span> aCQ;
&#125;

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">aCQ_delete</span><span class="hljs-params">(ArrayQueue* aCQ)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-built_in">free</span>(aCQ-&gt;<span class="hljs-built_in">array</span>);
    aCQ-&gt;<span class="hljs-built_in">array</span> = <span class="hljs-literal">NULL</span>;
    <span class="hljs-built_in">free</span>(aCQ);
    aCQ = <span class="hljs-literal">NULL</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">aCQ_empty</span><span class="hljs-params">(ArrayQueue* aCQ)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">if</span> (aCQ-&gt;<span class="hljs-built_in">free</span> == aCQ-&gt;nOfQueue) &#123;
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    &#125;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">enQueue</span><span class="hljs-params">(ArrayQueue* aCQ, <span class="hljs-keyword">int</span> var)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> == aCQ-&gt;<span class="hljs-built_in">free</span>) &#123;
        <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
    &#125;
    aCQ-&gt;<span class="hljs-built_in">array</span>[aCQ-&gt;writePointer] = var;
    <span class="hljs-comment">// aCQ-&gt;writePointer=(aCQ-&gt;writePointer+1)%(aCQ-&gt;nOfQueue);</span>
    aCQ-&gt;writePointer++;
    aCQ-&gt;<span class="hljs-built_in">free</span>--;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">deQueue</span><span class="hljs-params">(ArrayQueue* aCQ)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">if</span> (aCQ-&gt;<span class="hljs-built_in">free</span> == aCQ-&gt;nOfQueue) &#123;
        <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
    &#125;
    <span class="hljs-keyword">int</span> data = aCQ-&gt;<span class="hljs-built_in">array</span>[aCQ-&gt;readPointer];
    <span class="hljs-comment">// aCQ-&gt;readPointer=(aCQ-&gt;readPointer+1)%(aCQ-&gt;nOfQueue);</span>
    aCQ-&gt;readPointer++;
    aCQ-&gt;<span class="hljs-built_in">free</span>++;
    <span class="hljs-keyword">return</span> data;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">headOfQueue</span><span class="hljs-params">(ArrayQueue* aCQ)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">return</span> aCQ-&gt;<span class="hljs-built_in">array</span>[aCQ-&gt;readPointer];
&#125;</code></pre>
</details>
<pre><code class="hljs c"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">bfs</span><span class="hljs-params">(chain* array2d, <span class="hljs-keyword">int</span> vv, <span class="hljs-keyword">int</span> source, <span class="hljs-keyword">int</span>* preNode, <span class="hljs-keyword">int</span>* disFromSource)</span></span>
<span class="hljs-function"></span>&#123;
    ArrayQueue* <span class="hljs-built_in">queue</span> = aCQ_create(vv);

    <span class="hljs-comment">/* 所有和起点相邻的点的距离，设置他们的前一个点为起点 */</span>
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; vv; i++) &#123;
        disFromSource[i] = <span class="hljs-number">0</span>;
        preNode[i] = <span class="hljs-number">-1</span>;
    &#125;
    ChainNode* it = array2d[source].first;
    <span class="hljs-keyword">while</span> (it != <span class="hljs-literal">NULL</span>) &#123;
        disFromSource[it-&gt;element] = it-&gt;weight;
        preNode[it-&gt;element] = source;
        it = it-&gt;next;
    &#125;
    disFromSource[source] = <span class="hljs-number">0</span>;
    preNode[source] = <span class="hljs-number">-2</span>;

    enQueue(<span class="hljs-built_in">queue</span>, source);

    <span class="hljs-keyword">while</span> (!aCQ_empty(<span class="hljs-built_in">queue</span>)) &#123;
        <span class="hljs-keyword">int</span> v = deQueue(<span class="hljs-built_in">queue</span>);

        <span class="hljs-comment">/* 更新所有和 v 相邻， 没到过或者距离可以更小的点，且没到过则入队列 */</span>
        ChainNode* iterator = array2d[v].first;
        <span class="hljs-keyword">while</span> (iterator != <span class="hljs-literal">NULL</span>) &#123;
            <span class="hljs-keyword">if</span> ((preNode[iterator-&gt;element] == <span class="hljs-number">-1</span> || disFromSource[iterator-&gt;element] &gt; disFromSource[v] + iterator-&gt;weight)) &#123;
                disFromSource[iterator-&gt;element] = disFromSource[v] + iterator-&gt;weight;
                enQueue(<span class="hljs-built_in">queue</span>, iterator-&gt;element);  <span class="hljs-comment">// 其实队列中可能重复，但问题不大</span>
                preNode[iterator-&gt;element] = v;
            &#125;
            iterator = iterator-&gt;next;
        &#125;
    &#125;
    <span class="hljs-comment">// printf(&quot;success!\n&quot;);</span>
    preNode[source] = <span class="hljs-number">-2</span>;
    aCQ_delete(<span class="hljs-built_in">queue</span>);
&#125;</code></pre>
<h2 id="dfs"><a class="markdownIt-Anchor" href="#dfs"></a> DFS</h2>
<details>
<summary>栈</summary>
<pre><code class="hljs c"><span class="hljs-comment">/* 栈 */</span>
<span class="hljs-keyword">typedef</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">arrayStack</span> &#123;</span>
    <span class="hljs-keyword">int</span> nOfArray;
    <span class="hljs-keyword">int</span>* <span class="hljs-built_in">array</span>;
    <span class="hljs-keyword">int</span> pointer;
&#125; ArrayStack;

<span class="hljs-function">ArrayStack* <span class="hljs-title">aS_create</span><span class="hljs-params">(<span class="hljs-keyword">int</span> nOfArray)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">aS_delete</span><span class="hljs-params">(ArrayStack* aS)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">empty</span><span class="hljs-params">(ArrayStack* aS)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">push</span><span class="hljs-params">(ArrayStack* aS, <span class="hljs-keyword">int</span> var)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">pop</span><span class="hljs-params">(ArrayStack* aS)</span></span>;

<span class="hljs-function">ArrayStack* <span class="hljs-title">aS_create</span><span class="hljs-params">(<span class="hljs-keyword">int</span> nOfArray)</span></span>
<span class="hljs-function"></span>&#123;
    ArrayStack* aS = (ArrayStack*)<span class="hljs-built_in">malloc</span>(<span class="hljs-keyword">sizeof</span>(ArrayStack));
    aS-&gt;nOfArray = nOfArray;
    aS-&gt;pointer = <span class="hljs-number">0</span>;
    aS-&gt;<span class="hljs-built_in">array</span> = (<span class="hljs-keyword">int</span>*)<span class="hljs-built_in">malloc</span>(nOfArray * <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">int</span>));
    <span class="hljs-keyword">return</span> aS;
&#125;

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">aS_delete</span><span class="hljs-params">(ArrayStack* aS)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-built_in">free</span>(aS-&gt;<span class="hljs-built_in">array</span>);
    aS-&gt;<span class="hljs-built_in">array</span> = <span class="hljs-literal">NULL</span>;
    <span class="hljs-built_in">free</span>(aS);
    aS = <span class="hljs-literal">NULL</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">inline</span> <span class="hljs-keyword">int</span> <span class="hljs-title">empty</span><span class="hljs-params">(ArrayStack* aS)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> == aS-&gt;pointer) &#123;
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    &#125;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">inline</span> <span class="hljs-keyword">int</span> <span class="hljs-title">push</span><span class="hljs-params">(ArrayStack* aS, <span class="hljs-keyword">int</span> var)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">if</span> (aS-&gt;pointer &lt; (aS-&gt;nOfArray - <span class="hljs-number">1</span>)) &#123;
        aS-&gt;<span class="hljs-built_in">array</span>[aS-&gt;pointer] = var;
        aS-&gt;pointer += <span class="hljs-number">1</span>;
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    &#125;
    <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">inline</span> <span class="hljs-keyword">int</span> <span class="hljs-title">pop</span><span class="hljs-params">(ArrayStack* aS)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">if</span> (!empty(aS)) &#123;
        aS-&gt;pointer -= <span class="hljs-number">1</span>;
        <span class="hljs-keyword">return</span> aS-&gt;<span class="hljs-built_in">array</span>[aS-&gt;pointer];
    &#125;
    <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
&#125;</code></pre>
</details>
<pre><code class="hljs c"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">dfs</span><span class="hljs-params">(chain* array2d, <span class="hljs-keyword">int</span> vv, <span class="hljs-keyword">int</span> source, <span class="hljs-keyword">int</span>* preNode, <span class="hljs-keyword">int</span>* disFromSource)</span></span>
<span class="hljs-function"></span>&#123;
    ArrayStack* <span class="hljs-built_in">stack</span> = aS_create(vv);
    push(<span class="hljs-built_in">stack</span>, source);

    <span class="hljs-comment">/* 所有和起点相邻的点的距离，设置他们的前一个点为起点 */</span>
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; vv; i++) &#123;
        disFromSource[i] = <span class="hljs-number">0</span>;
        preNode[i] = <span class="hljs-number">-1</span>;
    &#125;
    ChainNode* it = array2d[source].first;
    <span class="hljs-keyword">while</span> (it != <span class="hljs-literal">NULL</span>) &#123;
        disFromSource[it-&gt;element] = it-&gt;weight;
        preNode[it-&gt;element] = source;
        it = it-&gt;next;
    &#125;
    disFromSource[source] = <span class="hljs-number">0</span>;
    preNode[source] = <span class="hljs-number">-2</span>;

    <span class="hljs-keyword">while</span> (!empty(<span class="hljs-built_in">stack</span>)) &#123;
        <span class="hljs-keyword">int</span> v = pop(<span class="hljs-built_in">stack</span>);

        <span class="hljs-comment">/* 更新所有和 v 相邻， 没到过或者距离可以更小的点，且没到过则入栈 */</span>
        ChainNode* iterator = array2d[v].first;
        <span class="hljs-keyword">while</span> (iterator != <span class="hljs-literal">NULL</span>) &#123;
            <span class="hljs-keyword">if</span> ((preNode[iterator-&gt;element] == <span class="hljs-number">-1</span> || disFromSource[iterator-&gt;element] &gt; disFromSource[v] + iterator-&gt;weight)) &#123;
                disFromSource[iterator-&gt;element] = disFromSource[v] + iterator-&gt;weight;
                push(<span class="hljs-built_in">stack</span>, iterator-&gt;element);
                preNode[iterator-&gt;element] = v;
            &#125;
            iterator = iterator-&gt;next;
        &#125;
    &#125;
    preNode[source] = <span class="hljs-number">-2</span>;
    aS_delete(<span class="hljs-built_in">stack</span>);
&#125;</code></pre>
<h1 id="附录调用和输出"><a class="markdownIt-Anchor" href="#附录调用和输出"></a> 附录（调用和输出）</h1>
<pre><code class="hljs c"><span class="hljs-function"><span class="hljs-keyword">int</span>* <span class="hljs-title">shortestPath</span><span class="hljs-params">(<span class="hljs-keyword">int</span> u, <span class="hljs-keyword">int</span> v, <span class="hljs-keyword">char</span> algorithm[])</span></span>
<span class="hljs-function"></span>&#123;
    FILE* fp = <span class="hljs-literal">NULL</span>;
    <span class="hljs-keyword">int</span> vv, ww;
    <span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">int</span>* re2 = <span class="hljs-literal">NULL</span>;
    <span class="hljs-keyword">int</span> none = <span class="hljs-number">0</span>;

    fp = fopen(fileNameWithPath, <span class="hljs-string">&quot;r&quot;</span>);
    <span class="hljs-keyword">if</span> (<span class="hljs-literal">NULL</span> == fp) &#123;
        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;fopen()error ! Please check your FILEPATH !\n&quot;</span>);
        <span class="hljs-built_in">exit</span>(<span class="hljs-number">-1</span>);
    &#125;
    <span class="hljs-built_in">fscanf</span>(fp, <span class="hljs-string">&quot;%d %d&quot;</span>, &amp;vv, &amp;ww);
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;1: %d %d\n&quot;</span>, vv, ww);

    <span class="hljs-keyword">if</span> (u &lt; <span class="hljs-number">0</span> || v &lt; <span class="hljs-number">0</span> || u &gt; vv || v &gt; vv) &#123;
        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;check your u and v\n&quot;</span>);
        <span class="hljs-built_in">exit</span>(<span class="hljs-number">-1</span>);
    &#125;

    chain* ln = read(fp, vv, ww);
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;read successfully !\n&quot;</span>);

    <span class="hljs-keyword">int</span> preNode[vv];
    <span class="hljs-keyword">int</span> disFromSource[vv];

    gettimeofday(&amp;tv2, <span class="hljs-literal">NULL</span>);
    ms_cont = (tv2.tv_sec - tv1.tv_sec) * <span class="hljs-number">1000</span> + (<span class="hljs-keyword">double</span>)(tv2.tv_usec - tv1.tv_usec) / <span class="hljs-number">1000</span>;
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;time used:%lf ms\n&quot;</span>, ms_cont);

    <span class="hljs-keyword">if</span> (algorithm[<span class="hljs-number">0</span>] == <span class="hljs-string">&#x27;D&#x27;</span> &amp;&amp; algorithm[<span class="hljs-number">1</span>] == <span class="hljs-string">&#x27;i&#x27;</span> &amp;&amp; algorithm[<span class="hljs-number">2</span>] == <span class="hljs-string">&#x27;j&#x27;</span>) &#123;
        none++;
        dijkstra(ln, vv, u, v, preNode, disFromSource);
    &#125;
    <span class="hljs-keyword">if</span> (algorithm[<span class="hljs-number">0</span>] == <span class="hljs-string">&#x27;D&#x27;</span> &amp;&amp; algorithm[<span class="hljs-number">1</span>] == <span class="hljs-string">&#x27;F&#x27;</span> &amp;&amp; algorithm[<span class="hljs-number">2</span>] == <span class="hljs-string">&#x27;S&#x27;</span>) &#123;
        none++;
        dfs(ln, vv, u, preNode, disFromSource);
    &#125;
    <span class="hljs-keyword">if</span> (algorithm[<span class="hljs-number">0</span>] == <span class="hljs-string">&#x27;B&#x27;</span> &amp;&amp; algorithm[<span class="hljs-number">1</span>] == <span class="hljs-string">&#x27;F&#x27;</span> &amp;&amp; algorithm[<span class="hljs-number">2</span>] == <span class="hljs-string">&#x27;S&#x27;</span>) &#123;
        none++;
        bfs(ln, vv, u, preNode, disFromSource);
    &#125;

    <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> == none) &#123;
        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;check your algorithm name !\n&quot;</span>);
        <span class="hljs-built_in">exit</span>(<span class="hljs-number">-1</span>);
    &#125;
    re2 = outputPath(preNode, disFromSource, re2, u, v);
    deleteChain(ln);

    <span class="hljs-keyword">return</span> re2;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span>* <span class="hljs-title">outputPath</span><span class="hljs-params">(<span class="hljs-keyword">int</span>* preNode, <span class="hljs-keyword">int</span>* disFromSource, <span class="hljs-keyword">int</span>* re2, <span class="hljs-keyword">int</span> u, <span class="hljs-keyword">int</span> v)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">int</span> hh = v;
    hh = v;
    <span class="hljs-keyword">int</span> nOfPath = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">if</span> (<span class="hljs-number">-1</span> == preNode[hh]) &#123;
        re2 = <span class="hljs-literal">NULL</span>;
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    &#125;
    <span class="hljs-keyword">while</span> (preNode[hh] != <span class="hljs-number">-2</span>) &#123;
        <span class="hljs-comment">// printf(&quot;%3d&quot;,hh);</span>
        hh = preNode[hh];
        nOfPath++;
    &#125;
    <span class="hljs-keyword">if</span> (<span class="hljs-number">-1</span> == preNode[hh]) &#123;
        <span class="hljs-keyword">return</span> re2;
    &#125;
    nOfPath++;
    <span class="hljs-comment">// printf(&quot;nOfpath: %d\n&quot;,nOfPath);</span>
    re2 = (<span class="hljs-keyword">int</span>*)<span class="hljs-built_in">malloc</span>((nOfPath + <span class="hljs-number">4</span>) * <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">int</span>));
    re2[<span class="hljs-number">0</span>] = u;
    hh = v;
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = nOfPath - <span class="hljs-number">1</span>; i &gt; <span class="hljs-number">0</span>; i--) &#123;
        re2[i] = hh;
        hh = preNode[hh];
    &#125;
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot; nop: %d\n&quot;</span>, nOfPath);
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; nOfPath - <span class="hljs-number">1</span>; i++) &#123;
        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d -&gt; &quot;</span>, re2[i]);
    &#125;
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d&quot;</span>, re2[nOfPath - <span class="hljs-number">1</span>]);
    <span class="hljs-keyword">return</span> re2;
&#125;</code></pre>
<p>运行范例：<br />
<img src="https://tuchuangrrr.oss-cn-shenzhen.aliyuncs.com/img/最短路径时间2.png" srcset="/img/loading.gif"/></p>
<p>先把运行时间抹去了，没做读取优化，主要时间在读文件。。。单独测时时Dij只用了20ms左右结果读文件读了400ms ＞﹏＜ ，如果不是一行一行读而是直接把整个文件读到一个字符数组中，甚至使用 mmap 直接读整个文件到内存，可以大幅度减少读取时间。 测试样本为经改造的 <code>https://snap.stanford.edu/data/amazon0601.txt.gz</code>，大概为60万行的11MB大小的文件。</p>
<h1 id="扩展阅读"><a class="markdownIt-Anchor" href="#扩展阅读"></a> 扩展阅读</h1>
<p>Floyd、Sollin、A* 等算法就先不放了，用在这个数据集也不太合适。</p>
<p>学习时还看到了几个大佬的方法，一个是 用 Fibonacci 堆实现的 Dijkstra 算法 ，一个是还没学会的 链式前向星 + SPFA，建议观摩：</p>
<p><a target="_blank" rel="noopener" href="http://greeensy.github.io/2013/04/16/Fibonacci-Dijkstra/">http://greeensy.github.io/2013/04/16/Fibonacci-Dijkstra/</a></p>
<p><a target="_blank" rel="noopener" href="https://www.cnblogs.com/crazyacking/p/3761686.html">https://www.cnblogs.com/crazyacking/p/3761686.html</a></p>

            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/categories/%E7%AE%97%E6%B3%95/">算法</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/tags/c/">c</a>
                    
                      <a class="hover-with-bg" href="/tags/%E7%AE%97%E6%B3%95/">算法</a>
                    
                      <a class="hover-with-bg" href="/tags/%E5%9B%BE%E8%AE%BA/">图论</a>
                    
                  </div>
                
              </div>
              
              
                <div class="post-prevnext row">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2020/07/python_Django/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">python_DJango</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2020/06/101_ncurse_learn/">
                        <span class="hidden-mobile">ncurses 学习</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
              <!-- Comments -->
              <article class="comments" id="comments">
                
                
  <div id="vcomments"></div>
  <script type="text/javascript">
    function loadValine() {
      addScript('https://cdn.staticfile.org/valine/1.4.14/Valine.min.js', function () {
        new Valine({
          el: "#vcomments",
          app_id: "iAgkjaR2s2ws1XXtS5sVxE7H-MdYXbMMI",
          app_key: "vKka6XRlblVTkbKz8jLXx6EQ",
          placeholder: "你是来自评论区的小惊喜吗 ...",
          path: window.location.pathname,
          avatar: "retro",
          meta: ["nick","mail"],
          pageSize: "10",
          lang: "zh-CN",
          highlight: false,
          recordIP: true,
          serverURLs: "",
        });
      });
    }
    waitElementVisible('vcomments', loadValine);
  </script>
  <noscript>Please enable JavaScript to view the <a target="_blank" href="https://valine.js.org" rel="nofollow noopener noopener">comments
      powered by Valine.</a></noscript>


<!-- 
  <div id="vcomments"></div>
  <script type="text/javascript">
    function loadValine() {
      addScript('https://cdn.staticfile.org/valine/1.4.14/Valine.min.js', function () {
        new Valine({
          el: "#vcomments",
          enableQQ: true,
          boolean: true,
          app_id: "iAgkjaR2s2ws1XXtS5sVxE7H-MdYXbMMI",
          app_key: "vKka6XRlblVTkbKz8jLXx6EQ",
          placeholder: "你是来自评论区的小惊喜吗 ...",
          path: "window.location.pathname",
          avatar: "retro",
          meta: "["nick","mail"]",
          pageSize: "10",
          lang: "zh-CN",
          highlight: false,
          recordIP: true,
          serverURLs: "",
            // 设置Bilibili表情包地址
            emojiCDN: '//i0.hdslb.com/bfs/emote/', 
            // 表情title和图片映射
            emojiMaps: {
            "tv_doge": "6ea59c827c414b4a2955fe79e0f6fd3dcd515e24.png",
            "tv_亲亲": "a8111ad55953ef5e3be3327ef94eb4a39d535d06.png",
            "tv_偷笑": "bb690d4107620f1c15cff29509db529a73aee261.png",
            "tv_再见": "180129b8ea851044ce71caf55cc8ce44bd4a4fc8.png",
            "tv_冷漠": "b9cbc755c2b3ee43be07ca13de84e5b699a3f101.png",
            "tv_发怒": "34ba3cd204d5b05fec70ce08fa9fa0dd612409ff.png",
            "tv_发财": "34db290afd2963723c6eb3c4560667db7253a21a.png",
            "tv_可爱": "9e55fd9b500ac4b96613539f1ce2f9499e314ed9.png",
            "tv_吐血": "09dd16a7aa59b77baa1155d47484409624470c77.png",
            "tv_呆": "fe1179ebaa191569b0d31cecafe7a2cd1c951c9d.png",
            "tv_呕吐": "9f996894a39e282ccf5e66856af49483f81870f3.png",
            "tv_困": "241ee304e44c0af029adceb294399391e4737ef2.png",
            "tv_坏笑": "1f0b87f731a671079842116e0991c91c2c88645a.png",
            "tv_大佬": "093c1e2c490161aca397afc45573c877cdead616.png",
            "tv_大哭": "23269aeb35f99daee28dda129676f6e9ea87934f.png",
            "tv_委屈": "d04dba7b5465779e9755d2ab6f0a897b9b33bb77.png",
            "tv_害羞": "a37683fb5642fa3ddfc7f4e5525fd13e42a2bdb1.png",
            "tv_尴尬": "7cfa62dafc59798a3d3fb262d421eeeff166cfa4.png",
            "tv_微笑": "70dc5c7b56f93eb61bddba11e28fb1d18fddcd4c.png",
            "tv_思考": "90cf159733e558137ed20aa04d09964436f618a1.png",
            "tv_惊吓": "0d15c7e2ee58e935adc6a7193ee042388adc22af.png",
            "tv_打脸": "56ab10b624063e966bfcb76ea5dc4794d87dfd47.png",
            "tv_抓狂": "fe31c08edad661d63762b04e17b8d5ae3c71a757.png",
            "tv_抠鼻": "c666f55e88d471e51bbd9fab9bb308110824a6eb.png",
            "tv_斜眼笑": "911f987aa8bc1bee12d52aafe62bc41ef4474e6c.png",
            "tv_无奈": "ea8ed89ee9878f2fece2dda0ea8a5dbfe21b5751.png",
            "tv_晕": "5443c22b4d07fb1907ccc610c8e6db254f2461b7.png",
            "tv_流汗": "cead1c351ab8d79e9f369605beb90148db0fbed3.png",
            "tv_流泪": "7e71cde7858f0cd50d74b0264aa26db612a8a167.png",
            "tv_流鼻血": "c32d39db2737f89b904ca32700d140a9241b0767.png",
            "tv_点赞": "f85c354995bd99e28fc76c869bfe42ba6438eff4.png",
            "tv_生气": "26702dcafdab5e8225b43ffd23c94ac1ff932654.png",
            "tv_生病": "8b0ec90e6b86771092a498c54f09fc94621c1900.png",
            "tv_疑问": "0793d949b18d7be716078349c202c15ff166f314.png",
            "tv_白眼": "c1d59f439e379ee50eef488bcb5e5378e5044ea4.png",
            "tv_皱眉": "72ccad6679fea0d14cce648b4d818e09b8ffea2d.png",
            "tv_目瞪口呆": "0b8cb81a68de5d5365212c99375e7ace3e7891b7.png",
            "tv_睡着": "8b196675b53af58264f383c50ad0945048290b33.png",
            "tv_笑哭": "1abc628f6d4f4caf9d0e7800878f4697abbc8273.png",
            "tv_腼腆": "89712c0d4af73e67f89e35cbc518420380a7f6f4.png",
            "tv_色": "61822c7e9aae5da76475e7892534545336b23a6f.png",
            "tv_调侃": "4bc022533ef31544ca0d72c12c808cf4a1cce3e3.png",
            "tv_调皮": "b9c41de8e82dd7a8515ae5e3cb63e898bf245186.png",
            "tv_鄙视": "6e72339f346a692a495b123174b49e4e8e781303.png",
            "tv_闭嘴": "c9e990da7f6e93975e25fd8b70e2e290aa4086ef.png",
            "tv_难过": "87f46748d3f142ebc6586ff58860d0e2fc8263ba.png",
            "tv_馋": "fc7e829b845c43c623c8b490ee3602b7f0e76a31.png",
            "tv_鬼脸": "0ffbbddf8a94d124ca2f54b360bbc04feb6bbfea.png",
            "tv_黑人问号": "45821a01f51bc867da9edbaa2e070410819a95b2.png",
            "tv_鼓掌": "1d21793f96ef4e6f48b23e53e3b9e42da833a0f6.png"
                // ... 更多表情
            }
        });
      });
    }
    createObserver(loadValine, 'vcomments');
  </script>
      <style>
        #vcomments textarea {
            box-sizing: border-box;
            background: url("/img/v2-f3d5c26e7ac0da80ee72b6dc178d6aa1_b005.gif") 100% 100% no-repeat;
        }
      </style>
  <noscript>Please enable JavaScript to view the <a target="_blank" href="https://valine.js.org" rel="nofollow noopener noopener">comments
      powered by Valine.</a></noscript>
 -->

              </article>
            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div id="tocbot"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->

  <div class="col-lg-7 mx-auto nopadding-md">
    <div class="container custom post-content mx-auto">
      <img src="/img/371905140-ROBOT-WAVING-400px-unscreen(1).gif" srcset="/img/loading.gif" class="rounded mx-auto d-block mt-5" style="width:200px; height:200px;" >
    </div>
  </div>


    
  </main>

  
    <a id="scroll-top-button" href="#" role="button">
      <i class="iconfont icon-arrowup" aria-hidden="true"></i>
    </a>
  

  
    <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
  

  

  

  <footer class="mt-5">
  <div class="text-center py-3">
    <div>
      <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a>
      <i class="iconfont icon-love"></i>
      <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener">
        <span>Fluid</span></a>
        <br>
        <span>©2019 - 2020 By</span>
        <a href="https://github.com/rainrime" target="_blank" rel="nofollow noopener"><span>kunzh</span></a>
    </div>
    
  <div class="statistics">
    
    

    
      
        <!-- 不蒜子统计PV -->
        <span id="busuanzi_container_site_pv" style="display: none">
            总访问量 
            <span id="busuanzi_value_site_pv"></span>
             次
          </span>
      
      
        <!-- 不蒜子统计UV -->
        <span id="busuanzi_container_site_uv" style="display: none">
            总访客数 
            <span id="busuanzi_value_site_uv"></span>
             人
          </span>
      
    
  </div>


    

    
  </div>
</footer>


<!-- SCRIPTS -->
<script  src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js" ></script>
<script  src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js" ></script>
<script  src="/js/debouncer.js" ></script>
<script  src="/js/main.js" ></script>

<!-- Plugins -->


  
    <script  src="/js/lazyload.js" ></script>
  



  



  <script defer src="https://cdn.staticfile.org/clipboard.js/2.0.6/clipboard.min.js" ></script>
  <script  src="/js/clipboard-use.js" ></script>



  <script defer src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>





  <script  src="https://cdn.staticfile.org/tocbot/4.11.1/tocbot.min.js" ></script>
  <script>
    $(document).ready(function () {
      var boardCtn = $('#board-ctn');
      var boardTop = boardCtn.offset().top;

      tocbot.init({
        tocSelector: '#tocbot',
        contentSelector: '#post-body',
        headingSelector: 'h1,h2,h3,h4,h5,h6',
        linkClass: 'tocbot-link',
        activeLinkClass: 'tocbot-active-link',
        listClass: 'tocbot-list',
        isCollapsedClass: 'tocbot-is-collapsed',
        collapsibleClass: 'tocbot-is-collapsible',
        collapseDepth: 6,
        scrollSmooth: true,
        headingsOffset: -boardTop
      });
      if ($('.toc-list-item').length > 0) {
        $('#toc').css('visibility', 'visible');
      }
    });
  </script>



  <script  src="https://cdn.staticfile.org/typed.js/2.0.11/typed.min.js" ></script>
  <script>
    var typed = new Typed('#subtitle', {
      strings: [
        '  ',
        "Dijkstra BFS DFS 最短路径&nbsp;",
      ],
      cursorChar: "_",
      typeSpeed: 70,
      loop: false,
    });
    typed.stop();
    $(document).ready(function () {
      $(".typed-cursor").addClass("h2");
      typed.start();
    });
  </script>



  <script  src="https://cdn.staticfile.org/anchor-js/4.2.2/anchor.min.js" ></script>
  <script>
    anchors.options = {
      placement: "right",
      visible: "hover",
      
      icon: "❡"
      
    };
    var el = "h1,h2,h3,h4,h5,h6".split(",");
    var res = [];
    for (item of el) {
      res.push(".markdown-body > " + item)
    }
    anchors.add(res.join(", "))
  </script>



  <script  src="/js/local-search.js" ></script>
  <script>
    var path = "/local-search.xml";
    var inputArea = document.querySelector("#local-search-input");
    inputArea.onclick = function () {
      searchFunc(path, 'local-search-input', 'local-search-result');
      this.onclick = null
    }
  </script>



  <script  src="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.css" />

  <script>
    $('#post img:not(.no-zoom img, img[no-zoom]), img[zoom]').each(
      function () {
        var element = document.createElement('a');
        $(element).attr('data-fancybox', 'images');
        $(element).attr('href', $(this).attr('src'));
        $(this).wrap(element);
      }
    );
  </script>







  
  
    <script type="text/javascript">
      //定义获取词语下标
      var a_idx = 0;
      jQuery(document).ready(function ($) {
        //点击body时触发事件
        $("body").click(function (e) {
          //需要显示的词语
          var a = new Array("富强", "民主", "文明", "和谐", "自由", "平等", "公正", "法治", "爱国", "敬业", "诚信", "友善");
          //设置词语给span标签
          var $i = $("<span/>").text(a[a_idx]);
          //下标等于原来下标+1  余 词语总数
          a_idx = (a_idx + 1) % a.length;
          //获取鼠标指针的位置，分别相对于文档的左和右边缘。
          //获取x和y的指针坐标
          var x = e.pageX, y = e.pageY;
          //在鼠标的指针的位置给$i定义的span标签添加css样式
          $i.css({
            "z-index": 999,
            "top": y - 20,
            "left": x,
            "position": "absolute",
            "font-weight": "bold",
            "color": rand_color()
          });
          // 随机颜色
          function rand_color() {
            return "rgb(" + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + ")"
          }
          //在body添加这个标签
          $("body").append($i);
          //animate() 方法执行 CSS 属性集的自定义动画。
          //该方法通过CSS样式将元素从一个状态改变为另一个状态。CSS属性值是逐渐改变的，这样就可以创建动画效果。
          //详情请看http://www.w3school.com.cn/jquery/effect_animate.asp
          $i.animate({
            //将原来的位置向上移动180
            "top": y - 180,
            "opacity": 0
            //1500动画的速度
          }, 1500, function () {
            //时间到了自动删除
            $i.remove();
          });
        });
      })
      ;
    </script>
  



  <script>(function (i, s, o, g, r, a, m) {
      i['DaoVoiceObject'] = r;
      i[r] = i[r] ||
        function () {
          (i[r].q = i[r].q || []).push(arguments);
        };
      i[r].l = 1 * new Date();
      a = s.createElement(o);
      m = s.getElementsByTagName(o)[0];
      a.async = 1;
      a.src = g;
      a.charset = 'utf-8';
      m.parentNode.insertBefore(a, m);
    })(window, document, 'script', ('https:' === document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/244aa65c.js", 'daovoice');
    daovoice('init', {
      app_id: "244aa65c",
    });
    daovoice('update');
  </script>









  

  

  

  

  

  





</body>
</html>
